﻿using System;
using System.IO;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using ScintillaNet;

namespace MyNotepad
{
    public partial class TabbedNote : DockContent
    {
        string filename;
        FileInfo info;
        bool isSaved, isDirty;

        public TabbedNote()
        {
            InitializeComponent();
            this.TabText = "My Unsaved Note";
            isSaved = false;
            isDirty = false;
            info = null;
        }

        public Scintilla ScintillaContent
        {
            get { return this.containedText; }
            set { this.containedText = value; }
        }

        public TabbedNote(FileInfo f)
        {
            InitializeComponent();
            info = f;

            try
            {
                LoadText(f.FullName);
            }
            catch (IOException err)
            {
                MessageBox.Show(err.Message, "My Notepad", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            this.TabText = f.Name;
            isSaved = true;
            isDirty = false;
            filename = f.Name;

            ChangeOnOpenorSave(f.Extension);            
        }

        private void ChangeOnOpenorSave(string ext)
        {
            ext = ext.ToLower();
            switch (ext)
            {
                case ".c":
                    LanguageChange("c");
                    break;
                case ".cpp":
                    LanguageChange("cpp");
                    break;
                case ".cs":
                    LanguageChange("cs");
                    break;
                case ".html":
                case ".htm":
                    LanguageChange("html");
                    break;
                case ".java":
                    LanguageChange("java");
                    break;
            }
        }

        void LoadText(string file)
        {
            StreamReader toRead = new StreamReader(file);
            ContainedText = toRead.ReadToEnd();
            toRead.Close();
        }

        public bool Saved
        {
            get { return isSaved; }
            set { isSaved = value; }
        }

        public bool Dirty
        {
            get { return isDirty; }
            set { isDirty = value; }
        }

        public string ContainedText
        {
            get { return containedText.Text; }
            set { containedText.Text = value; }
        }

        private void SaveAs(string name)
        {
            try
            {
                StreamWriter toWrite = new StreamWriter(name);
                toWrite.Write(ContainedText);
                toWrite.Close();
                filename = name;
                isDirty = false;
                isSaved = true;
                FileInfo f = new FileInfo(name);
                this.TabText = f.Name;
                info = f;
                ChangeOnOpenorSave(f.Extension);
            }
            catch (IOException err)
            {
                MessageBox.Show(err.Message, "My Notepad", MessageBoxButtons.OK, MessageBoxIcon.Error);            
            }
        }

        public void Save()
        {
            if (isSaved)
            {
                if (isDirty)
                    SaveAs(filename);
            }
            else
                SaveFileAs();
        }

        private void ContainedTextChanged(object sender, EventArgs e)
        {
            //isDirty = true;
        }

        public void SaveFileAs()
        {
            SaveFileDialog save = new SaveFileDialog();
            save.Title = "Save As...";
            string filter = "C Files (*.c)|*.c|";
            filter += "C++ Files (*.cpp)|*.cpp|";
            filter += "C# Files (*.cs)|*.cs|";
            filter += "Java Files (*.java)|*.java|";
            filter += "HTML Files (*.html)|*.html|";
            filter += "Text Files (*.txt)|*.txt|";
            filter += "All Files (*.*)|*.*";
            save.Filter = filter;
            save.AddExtension = true;
            save.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            save.DefaultExt = ".txt";
            if (save.ShowDialog() == DialogResult.OK)
                SaveAs(save.FileName);
        }

        public FileInfo Info
        {
            get { return this.info; }
        }

        private void NoteClosing(object sender, FormClosingEventArgs e)
        {
            if (isDirty)
            {
                string str = "";
                if (info == null)
                    str = "File not saved. Would you like to save it?";
                else
                    str = "File " + info.Name + " not saved. Would you like to save it?";
                DialogResult rslt = MessageBox.Show(str, "My Notepad", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
                switch (rslt)
                {
                    case DialogResult.Yes:
                        if (isSaved)
                            SaveAs(this.filename);
                        else
                        {
                            SaveFileDialog save = new SaveFileDialog();
                            save.Title = "Save As...";
                            save.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
                            DialogResult saveRslt = save.ShowDialog();
                            switch (saveRslt)
                            {
                                case DialogResult.OK:
                                    SaveAs(save.FileName);
                                    break;
                                case DialogResult.Cancel:
                                    e.Cancel = true;
                                    break;
                            }
                        }
                        break;
                    case DialogResult.Cancel:
                        e.Cancel = true;
                        break;
                }
            }
        }

        private void TextInserted(object sender, TextModifiedEventArgs e)
        {
            isDirty = true;
            if (!this.TabText.StartsWith("*"))
            {
                string str = this.TabText.Insert(0, "*");
                this.TabText = str;
            }
        }

        private void TextDeleted(object sender, TextModifiedEventArgs e)
        {
            isDirty = true;
            if (!this.TabText.StartsWith("*"))
            {
                string str = this.TabText.Insert(0, "*");
                this.TabText = str;
            }
        }

        public void LanguageChange(string lang)
        {
            try
            {
                switch (lang)
                {
                    case "c":
                        containedText.ConfigurationManager.Language = "c";
                        containedText.Lexing.Colorize();
                        break;
                    case "cpp":
                        containedText.ConfigurationManager.Language = "cpp";
                        containedText.Lexing.Colorize();
                        break;
                    case "cs":
                        containedText.ConfigurationManager.Language = "cs";
                        containedText.Lexing.Colorize();
                        break;
                    case "html":
                        containedText.ConfigurationManager.Language = "html";
                        containedText.Lexing.Colorize();
                        break;
                    case "java":
                        containedText.ConfigurationManager.Language = "java";
                        containedText.Lexing.Colorize();
                        break;
                }
            }
            catch (FileNotFoundException)
            {
                switch (lang)
                {
                    case "c":
                        if (!Properties.Settings.Default.c)
                        {
                            ShowNotFoundError(lang);
                            Properties.Settings.Default.c = true;                            
                        }
                        break;
                    case "cpp":
                        if (!Properties.Settings.Default.cpp)
                        {
                            ShowNotFoundError(lang);
                            Properties.Settings.Default.cpp = true;
                        }
                        break;
                    case "cs":
                        if (!Properties.Settings.Default.cs)
                        {
                            ShowNotFoundError(lang);
                            Properties.Settings.Default.cs = true;
                        }
                        break;
                    case "html":
                        if (!Properties.Settings.Default.html)
                        {
                            ShowNotFoundError(lang);
                            Properties.Settings.Default.html = true;
                        }
                        break;
                    case "java":
                        if (!Properties.Settings.Default.java)
                        {
                            ShowNotFoundError(lang);
                            Properties.Settings.Default.java = true;
                        }
                        break;
                }
                Properties.Settings.Default.Save();
            }
        }

        private void ShowNotFoundError(string lang)
        {
            MessageBox.Show("The highlighter for " + lang + " was not found. This will not be shown again. Reinstall My Notepad to get it.", "My Notepad", MessageBoxButtons.OK, MessageBoxIcon.Warning);            
        }
    }
}
